package com.liu;
import com.liu.annotation_IOC.*;

import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;

public class Main2 {
    public static void main( String[] args) throws Exception {
        //装 类 全路径的集合
        HashSet<String> allClassPathSet = new HashSet<String>();
        //扫描指定包下的把.class 类的全限定名 全部放到 allClassPathSet中
        doScanner(allClassPathSet, "com.liu.annotation_IOC");
        for(String className : allClassPathSet) {
            Class<?> clazz = Class.forName(className);//获取该class实例
            //如果该类上有@CzyComponent注解，就直接将该类添加到ioc容器中
            if (clazz.isAnnotationPresent(CzyComponent.class)) {
                IOCContainer.putBean(className, clazz.newInstance());
            }
            //获取该该类中的所有方法
            Method[] methods = clazz.getDeclaredMethods();
            for(int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                if (method.isAnnotationPresent(CzyBean.class)) { //如果该方法上有@CzyBean注解
                    //获取beanName例如@CzyBean("b")即获取出；b
                    String beanName = method.getAnnotation(CzyBean.class).value();
                    System.out.println("beanName is "+ beanName);
                  if(beanName.equals("")){
                        //获取该方法的方法名字的小写字母作为参数
                        beanName = method.getName().toLowerCase();
                    }
                    //判断该方法是否为静态方法
                    if (Modifier.isStatic(method.getModifiers())) {
                        IOCContainer.putBean(beanName, method.invoke(null));//静态工厂创建实例
                    } else {
                        //从容器中获取当前这实例对象
                        //实例工厂创建实例
                       // System.out.println("classname"+ className);
                        // method.invoke 的第一个参数是method方法属于的对象，静态方法填充为null
                        IOCContainer.putBean(beanName, method.invoke(IOCContainer.getBean(className)));

                    }
                }
            }
        }


        //--------------------------使用容器-------------------------------
         B b = (B) IOCContainer.getBean("b");
         b.testB();

         C d = (C) IOCContainer.getBean("createcobject");
         d.testC();
         //hello
    }
    /**
     * 得到指定包下所有的class 的全路径
     * @param allClassPathSet:装载类全路径的集合
     * @param scanPackage：指定扫描的包路径
     * 注意：该方法为Main类中的静态方法
     */
    public static void doScanner(Set<String> allClassPathSet, String scanPackage) {
        URL url = Main2.class.getResource("/" + scanPackage.replaceAll("\\.", "/"));

//        System.out.println("URL = "+url.toString());
        File classDir = new File(url.getFile());
        for (File file : classDir.listFiles()) {
            if (file.isDirectory()) {
                //是文件夹,递归循环
                doScanner(allClassPathSet, scanPackage + "." + file.getName());
            } else {
                //如果文件不是.class结尾
                if (!file.getName().endsWith(".class")) {
                    continue;
                }
                //拼装类的全路径
                String clazzName = (scanPackage + "." + file.getName().replace(".class", ""));

                //添加到集合中
                allClassPathSet.add(clazzName);
            }
        }
    }
}
